package org.m2acsi.control;

import java.io.InputStream;
import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.annotation.ManagedBean;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.Part;
import org.m2acsi.boundary.ConsultationEJB;
import org.m2acsi.boundary.DocumentEJB;
import org.m2acsi.boundary.FileManager;
import org.m2acsi.boundary.OpinionEJB;
import org.m2acsi.entities.Consultation;
import org.m2acsi.entities.Document;
import org.m2acsi.entities.Opinion;
import org.m2acsi.entities.Task;
import org.m2acsi.entities.Upload;
import org.m2acsi.utils.Security;

@Named
@RequestScoped
@ManagedBean
public class OpinionBean extends BaseBean implements Serializable {

    private String opinionContent;
    private Opinion opinion;
    private Part uploadedFileOpinion;
    private Document document;
    private FileManager fm = new FileManager("Files");
    private List<Opinion> opinions;
    @Inject
    OpinionEJB opinionEjb;
    @Inject
    DocumentEJB documentEjb;
    @Inject
    private ConsultationEJB consultationEJB;

    public OpinionBean() {
        super();
    }

    public Part getUploadedFileOpinion() {
        return uploadedFileOpinion;
    }

    public void setUploadedFileOpinion(Part uploadedFileOpinion) {
        this.uploadedFileOpinion = uploadedFileOpinion;
    }

    public String getOpinionContent() {
        return opinionContent;
    }

    public void setOpinionContent(String opinionContent) {
        this.opinionContent = opinionContent;
    }

    public void save() {
        if (opinionContent != null && opinionContent.length() != 0) {
            String idTaskString = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id");
            Task tmpTask = Security.taskSecurityCheck(idTaskString, getAuthenticatedUser(), taskEjb, this);
            if (tmpTask.isFinished()) {
                try {
                    //Save the document
                    if (uploadedFileOpinion.getSize() != 0) {
                        InputStream is = uploadedFileOpinion.getInputStream();
                        //Get file name
                        String headerContent = uploadedFileOpinion.getHeader("content-disposition");
                        String nameFile = headerContent.substring((headerContent.substring(0, headerContent.length() - 1)).lastIndexOf("\"") + 1, headerContent.length() - 1);
                        //Save file on mongo
                        document = fm.uploadFile(is, nameFile);
                        //Create upload
                        Upload upload = new Upload(getAuthenticatedUser(), document);
                        document.setUpload(upload);
                        //Update list of docuementts of user
                        List<Upload> lUpload = getAuthenticatedUser().getUploads();
                        lUpload.add(upload);
                        getAuthenticatedUser().setUploads(lUpload);
                        documentEjb.save(document);
                        document = documentEjb.findDocument(document.getMongoId());
                    }

                    //Save the opinion
                    opinion = new Opinion(opinionContent);
                    opinion.setTask(tmpTask);
                    opinion.setUser(getAuthenticatedUser());
                    opinionEjb.save(opinion);
                    opinion.setDocument(document);
                    opinionEjb.update(opinion);
                    List<Opinion> opinions = tmpTask.getOpinions();
                    opinions.add(opinion);
                    tmpTask.setOpinions(opinions);
                    taskEjb.update(tmpTask);
                    consultationEJB.save(new Consultation(getAuthenticatedUser(), tmpTask));
                } catch (Exception e) {
                    //TODO: clean the document and mongo if needed
                    FacesContext.getCurrentInstance().addMessage("opinion-add-form:opinion-text", new FacesMessage("Something went wrong while trying to save this document."));
                }
                redirectWithMessage("/faces/user/index.xhtml", "Your opinion has been saved.");
            } else {
                hackRedirect("try to edit a closed task.");
            }
        } else {
            FacesContext.getCurrentInstance().addMessage("opinion-add-form:opinion-text", new FacesMessage("You forgot to leave a message... :)"));
        }
    }

    public Opinion getOpinion() {
        return opinion;
    }

    public void setOpinion(Opinion opinion) {
        this.opinion = opinion;
    }

    public boolean alreadySubmitAnOpinion() {
        Task tmpTask = Security.taskSecurityCheck(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id"), getAuthenticatedUser(), taskEjb, this);
        return !opinionEjb.alreadySubmitAnOpinion(tmpTask, getAuthenticatedUser());
    }

    public List<Opinion> getOpinions() {
        Task tmpTask = Security.taskSecurityCheck(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id"), getAuthenticatedUser(), taskEjb, this);
        Date lastVisit = consultationEJB.lastConsultationOnTaskDetails(tmpTask, getAuthenticatedUser());
        List<Opinion> opinions = opinionEjb.getOpinions(tmpTask);
        for (Iterator<Opinion> it = opinions.iterator(); it.hasNext();) {
            Opinion o = it.next();
            if (lastVisit == null) {
                o.setIsNew(true);
            } else {
                if (o.getCreationDate().compareTo(lastVisit) > 0) {
                    o.setIsNew(true);
                } else {
                    o.setIsNew(false);
                }
            }
        }
        return opinions;
    }
}
